/*
 * 光电传感器滤波快速入门示例
 * 
 * 最简单的光电传感器防误触发实现
 * 适合快速集成到现有项目中
 */

using System;
using System.Threading.Tasks;
using FXEtherCAT.SDK;

namespace PhotoelectricQuickStart
{
    class QuickStartExample
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine("=== 光电传感器滤波快速入门 ===");

            using var sdk = new FXEtherCATSDK();

            // 1. 配置实时监控线程（可选，用于更好的preempt-rt性能）
            if (Environment.ProcessorCount > 2)
            {
                // 多核系统：绑定到专用核心，设置高实时优先级
                sdk.ConfigureMonitorThread(2, 85);
                Console.WriteLine("✓ 实时监控线程已配置 (CPU核心2, 优先级85)");
            }
            else
            {
                // 单核或双核系统：使用中等优先级，不绑定核心
                sdk.ConfigureMonitorThread(-1, 60);
                Console.WriteLine("✓ 实时监控线程已配置 (不绑定核心, 优先级60)");
            }

            // 2. 配置滑动窗口滤波器（抗干扰光电传感器滤波）
            var filter = new ReadDataFilter
            {
                Type = FilterType.SlidingWindow,
                WindowSizeMs = 50,          // 滑动窗口大小 50ms（50个1ms采样）
                RisingThreshold = 40,       // 上升阈值：50个采样中至少40个为1才输出1
                FallingThreshold = 30,      // 下降阈值：50个采样中少于30个为1才输出0
                MonitoredBits = { },        // 空列表：监控整个值（适用于bool类型或整个uint8）
                Logic = BitLogic.Any,       // 位逻辑：任意位（对于空列表无影响）
                EdgeType = EdgeType.Both
            };

            // 配置滤波器到指定的光电传感器
            sdk.ConfigureReadDataFilter(0, 0x6000, 1, filter);
            Console.WriteLine("✓ 光电传感器滤波器已配置 (滑动窗口：50ms窗口, 40/30阈值, 监控整个值)");

            // 3. 注册回调事件 - 滑动窗口滤波在状态变化时触发
            sdk.SlaveReadDataChanged += (sender, e) =>
            {
                // 检查是否是我们关心的光电传感器
                if (e.SlaveNumber == 0 && e.Index == 0x6000 && e.Subindex == 1)
                {
                    // 滑动窗口滤波器会在输出状态变化时触发
                    if (e.NewValue == 1)
                    {
                        Console.WriteLine($"📦 物体检测到！时间: {DateTime.Now:HH:mm:ss.fff}");
                        Console.WriteLine($"   └─ 滑动窗口判定：稳定信号（已过滤干扰）");

                        // 在这里添加您的业务逻辑
                        OnObjectDetected();
                    }
                    else
                    {
                        Console.WriteLine($"📤 物体离开！时间: {DateTime.Now:HH:mm:ss.fff}");
                        Console.WriteLine($"   └─ 滑动窗口判定：信号消失（已过滤干扰）");

                        // 在这里添加您的业务逻辑
                        OnObjectLeft();
                    }
                }
            };

            // 4. 启动监控
            if (sdk.StartReadDataMonitoring())
            {
                Console.WriteLine("✓ 监控已启动，等待光电传感器信号...");

                // 验证实时配置（可选）
                if (sdk.VerifyMonitorThreadConfig(out int actualCore, out int actualPriority, out var actualPolicy))
                {
                    Console.WriteLine($"✓ 实时配置已生效 - 核心:{actualCore}, 优先级:{actualPriority}, 策略:{actualPolicy}");
                }

                Console.WriteLine("按任意键退出...");
                Console.ReadKey();
            }
            else
            {
                Console.WriteLine("❌ 启动监控失败");
            }
        }

        /// <summary>
        /// 物体检测到时的处理
        /// </summary>
        private static void OnObjectDetected()
        {
            // 在这里添加您的业务逻辑，例如：
            // - 记录物体进入事件
            // - 触发拍照/扫描
            // - 发送信号给PLC/其他设备
            // - 更新计数器
            // - 启动质检流程

            Console.WriteLine("  ➤ 执行动作: 物体进入处理（已过滤干扰）");
        }

        /// <summary>
        /// 物体离开时的处理
        /// </summary>
        private static void OnObjectLeft()
        {
            // 在这里添加您的业务逻辑，例如：
            // - 记录物体离开事件
            // - 完成处理流程
            // - 清理状态
            // - 准备下一个物体

            Console.WriteLine("  ➤ 执行动作: 物体离开处理（已过滤干扰）");
        }
    }
}

/*
 * 使用说明：
 *
 * 1. 实时监控线程配置：
 *    sdk.ConfigureMonitorThread(CPU核心, 实时优先级);
 *    - CPU核心: -1(不绑定), 0-N(绑定到指定核心)
 *    - 实时优先级: 0(默认调度), 1-99(实时优先级)
 *
 * 2. 修改传感器地址：
 *    sdk.ConfigureReadDataFilter(从站号, 索引, 子索引, filter);
 *
 * 3. 调整滑动窗口参数：
 *    WindowSizeMs = 30;        // 30ms窗口（快速响应）
 *    WindowSizeMs = 100;       // 100ms窗口（强抗干扰）
 *    RisingThreshold = 25;     // 30ms窗口中25个有效样本才输出1
 *    FallingThreshold = 15;    // 30ms窗口中少于15个有效样本才输出0
 *
 * 4. 选择检测类型：
 *    EdgeType.Rising  - 只检测物体进入
 *    EdgeType.Falling - 只检测物体离开
 *    EdgeType.Both    - 检测进入和离开（推荐）
 *
 * 5. 滑动窗口滤波器配置示例：
 *
 *    // 快速响应配置（30ms窗口）
 *    var fastResponse = new ReadDataFilter {
 *        Type = FilterType.SlidingWindow,
 *        WindowSizeMs = 30,      // 30ms窗口
 *        RisingThreshold = 25,   // 30个样本中25个有效
 *        FallingThreshold = 15,  // 30个样本中少于15个有效
 *        MonitoredBits = { },    // 监控整个值
 *        Logic = BitLogic.Any
 *    };
 *
 *    // 强抗干扰配置（100ms窗口）
 *    var strongFilter = new ReadDataFilter {
 *        Type = FilterType.SlidingWindow,
 *        WindowSizeMs = 100,     // 100ms窗口
 *        RisingThreshold = 80,   // 100个样本中80个有效
 *        FallingThreshold = 60,  // 100个样本中少于60个有效
 *        MonitoredBits = { },    // 监控整个值
 *        Logic = BitLogic.Any
 *    };
 *
 * 6. 位操作功能（适用于uint8等多位数据）：
 *    当PDO是uint8类型包含多个IO时，可以选择监控特定的位
 *
 *    // 示例：0x6000:1 是uint8，包含8个IO
 *    // Bit 7-4: 4个光电传感器, Bit 3-0: 4个按钮
 *
 *    // 只监控光电传感器1（第7位）
 *    var photoelectric1Filter = new ReadDataFilter {
 *        Type = FilterType.SlidingWindow,
 *        WindowSizeMs = 50,
 *        RisingThreshold = 40,
 *        FallingThreshold = 30,
 *        MonitoredBits = { 7 },      // 只监控Bit 7
 *        Logic = BitLogic.Any,       // 单个位时Any和All效果相同
 *        EdgeType = EdgeType.Both
 *    };
 *
 *    // 监控任意光电传感器（第7-4位）
 *    var anyPhotoelectricFilter = new ReadDataFilter {
 *        Type = FilterType.SlidingWindow,
 *        WindowSizeMs = 30,
 *        RisingThreshold = 25,
 *        FallingThreshold = 15,
 *        MonitoredBits = { 7, 6, 5, 4 },  // 监控4个光电传感器
 *        Logic = BitLogic.Any,            // 任意一个触发就算
 *        EdgeType = EdgeType.Both
 *    };
 *
 *    // 双光电防重复计数（两个都触发才算）
 *    var dualPhotoelectricFilter = new ReadDataFilter {
 *        Type = FilterType.SlidingWindow,
 *        WindowSizeMs = 50,
 *        RisingThreshold = 40,
 *        FallingThreshold = 30,
 *        MonitoredBits = { 7, 6 },        // 监控Bit 7和Bit 6
 *        Logic = BitLogic.All,            // 两个都为1才触发
 *        EdgeType = EdgeType.Both
 *    };
 *
 * 7. 实时性能优化：
 *
 *    // 高性能配置（多核系统）
 *    sdk.ConfigureMonitorThread(2, 85);  // 专用核心，高优先级
 *
 *    // 平衡配置
 *    sdk.ConfigureMonitorThread(-1, 60); // 不绑定核心，中等优先级
 *
 *    // 兼容配置
 *    sdk.ConfigureMonitorThread(-1, 0);  // 默认调度策略
 *
 * 8. 其他滤波器类型：
 *
 *    // 无滤波（直接触发，仅使用EdgeType控制）
 *    var noFilter = new ReadDataFilter
 *    {
 *        Type = FilterType.None,
 *        EdgeType = EdgeType.Rising
 *    };
 *
 *    // 计数滤波器（100ms内至少3次变化才触发）
 *    var countFilter = new ReadDataFilter
 *    {
 *        Type = FilterType.Count,
 *        CountThreshold = 3,
 *        TimeWindowMs = 100
 *    };
 *
 * 8. preempt-rt系统优化：
 *    - 使用实时内核: sudo apt-get install linux-image-rt-amd64
 *    - 设置权限: sudo setcap cap_sys_nice+ep ./程序名
 *    - 或使用root权限运行: sudo ./程序名
 */
